package org.javahispano.javacup.tacticas.tacticas_aceptadas.Sag;

import java.awt.Color;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.javahispano.javacup.modelo.*;
import java.util.List;
//import pdsanchez.prbs.Network;

public class Sag implements Tactica {

    Posicion alineacion1[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-12.125874125874127, -35.8710407239819),
        new Posicion(0.4755244755244755, -33.257918552036195),
        new Posicion(12.125874125874127, -35.63348416289593),
        new Posicion(7.526717557251908, -11.753731343283583),
        new Posicion(-8.564885496183205, -11.753731343283583),
        new Posicion(-14.97902097902098, 12.828054298642533),
        new Posicion(7.846153846153847, 16.153846153846153),
        new Posicion(-20.923076923076923, 40.62217194570136),
        new Posicion(-5.230769230769231, 33.73303167420815),
        new Posicion(9.272727272727272, 35.63348416289593)
    };
    Posicion alineacion2[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-8.083916083916083, -35.63348416289593),
        new Posicion(6.6573426573426575, -35.63348416289593),
        new Posicion(-1.4265734265734267, -19.95475113122172),
        new Posicion(-6.419580419580419, -3.088235294117647),
        new Posicion(8.564885496183205, -7.574626865671642),
        new Posicion(-7.846153846153847, 20.90497737556561),
        new Posicion(23.062937062937063, 20.90497737556561),
        new Posicion(-23.3006993006993, 10.927601809954751),
        new Posicion(14.027972027972028, 34.920814479638004),
        new Posicion(-6.895104895104895, 39.671945701357465)
    };
    Posicion alineacion3[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-4.5174825174825175, -26.606334841628957),
        new Posicion(1.6643356643356644, -26.84389140271493),
        new Posicion(13.076923076923078, -34.44570135746606),
        new Posicion(-14.74125874125874, -34.920814479638004),
        new Posicion(-0.23776223776223776, -9.502262443438914),
        new Posicion(-9.748251748251748, -17.816742081447966),
        new Posicion(12.125874125874127, -18.766968325791854),
        new Posicion(-6.6573426573426575, 17.57918552036199),
        new Posicion(3.804195804195804, 11.165158371040723),
        new Posicion(7.37062937062937, 29.457013574660635)
    };
    Posicion alineacion4[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-11.16030534351145, -31.082089552238806),
        new Posicion(11.16030534351145, -31.6044776119403),
        new Posicion(28.290076335877863, -28.470149253731343),
        new Posicion(-28.290076335877863, -28.470149253731343),
        new Posicion(11.16030534351145, -1.3059701492537314),
        new Posicion(-10.641221374045802, -0.7835820895522387),
        new Posicion(-27.251908396946565, 31.6044776119403),
        new Posicion(-10.641221374045802, 30.559701492537314),
        new Posicion(9.603053435114505, 28.992537313432837),
        new Posicion(25.69465648854962, 28.992537313432837)
    };
    Posicion alineacion5[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-11.16030534351145, -35.78358208955224),
        new Posicion(0.23776223776223776, -31.59502262443439),
        new Posicion(11.888111888111888, -35.8710407239819),
        new Posicion(5.230769230769231, -16.153846153846153),
        new Posicion(-6.895104895104895, -16.866515837104075),
        new Posicion(-17.356643356643357, -8.076923076923077),
        new Posicion(12.125874125874127, -7.839366515837104),
        new Posicion(-13.076923076923078, -2.1380090497737556),
        new Posicion(0.2595419847328244, -0.26119402985074625),
        new Posicion(3.804195804195804, -2.1380090497737556)
    };
    Posicion alineacion6[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-8.797202797202797, -36.10859728506787),
        new Posicion(-0.23776223776223776, -32.30769230769231),
        new Posicion(9.748251748251748, -35.63348416289593),
        new Posicion(5.706293706293707, -21.380090497737555),
        new Posicion(-6.419580419580419, -20.90497737556561),
        new Posicion(-17.594405594405593, -8.552036199095022),
        new Posicion(17.11888111888112, -8.789592760180994),
        new Posicion(6.4885496183206115, -6.529850746268657),
        new Posicion(-6.4885496183206115, -6.529850746268657),
        new Posicion(22.580152671755727, -1.3059701492537314)
    };

    public class TacticaDetalleImpl implements TacticaDetalle {

        @Override
        public String getNombre() {
            return "sagFC";
        }

        @Override
        public String getPais() {
            return "España";
        }

        @Override
        public String getEntrenador() {
            return "YoMismo";
        }

        @Override
        public Color getColorCamiseta() {
            return new Color(255, 255, 0);
        }

        @Override
        public Color getColorPantalon() {
            return new Color(0, 0, 51);
        }

        @Override
        public Color getColorFranja() {
            return new Color(0, 0, 0);
        }

        @Override
        public Color getColorCalcetas() {
            return new Color(255, 255, 0);
        }

        @Override
        public Color getColorPortero() {
            return new Color(51, 51, 51);
        }

        @Override
        public EstiloUniforme getEstilo() {
            return EstiloUniforme.SIN_ESTILO;
        }

        @Override
        public Color getColorCamiseta2() {
            return new Color(0, 51, 255);
        }

        @Override
        public Color getColorPantalon2() {
            return new Color(0, 0, 0);
        }

        @Override
        public Color getColorFranja2() {
            return new Color(255, 255, 255);
        }

        @Override
        public Color getColorCalcetas2() {
            return new Color(0, 0, 0);
        }

        @Override
        public Color getColorPortero2() {
            return new Color(102, 0, 153);
        }

        @Override
        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.SIN_ESTILO;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre = nombre;
                this.numero = numero;
                this.piel = piel;
                this.pelo = pelo;
                this.velocidad = velocidad;
                this.remate = remate;
                this.presicion = presicion;
                this.portero = portero;
            }

            @Override
            public String getNombre() {
                return nombre;
            }

            @Override
            public Color getColorPiel() {
                return piel;
            }

            @Override
            public Color getColorPelo() {
                return pelo;
            }

            @Override
            public int getNumero() {
                return numero;
            }

            @Override
            public boolean esPortero() {
                return portero;
            }

            @Override
            public double getVelocidad() {
                return velocidad;
            }

            @Override
            public double getRemate() {
                return remate;
            }

            @Override
            public double getPresicion() {
                return presicion;
            }
        }

        @Override
        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                        new JugadorImpl("Javi", 1, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.8d, 0.5d, true),
                        new JugadorImpl("Berto", 2, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.5d, 0.75d, false),
                        new JugadorImpl("Paudavy", 3, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.5d, 0.75d, false),
                        new JugadorImpl("Jorge", 4, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.54d, 0.74d, false),
                        new JugadorImpl("Raul", 5, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.53d, 0.76d, false),
                        new JugadorImpl("Richi", 6, new Color(255, 200, 150), new Color(50, 0, 0), 0.99d, 0.59d, 0.8d, false),
                        new JugadorImpl("Martin", 7, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.73d, 0.75d, false),
                        new JugadorImpl("Jose", 8, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.65d, 0.75d, false),
                        new JugadorImpl("Patxi", 9, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.92d, 0.95d, false),
                        new JugadorImpl("Chema", 10, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false),
                        new JugadorImpl("Monty", 11, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false)
                    };
        }
    }
    TacticaDetalle detalle = new TacticaDetalleImpl();

    @Override
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    @Override
    public Posicion[] getPosicionSaca(SituacionPartido sp) {
        return alineacion5;
    }

    @Override
    public Posicion[] getPosicionRecive(SituacionPartido sp) {
        return alineacion6;
    }
    //Network network = new Network(8, 5, 3, 0.5, 0.7);
    //Lista de comandos
    private List<Comando> comandos = new LinkedList<Comando>();
    private Jugador[] jugadores;
    private Jugador[] rivales;

    @Override
    public List<Comando> ejecutar(SituacionPartido sp) {
        //Limpia la lista de comandos
        comandos.clear();

        // Goles
        int golesSag = sp.golesPropios();
        int golesRival = sp.golesRival();

        // Posiciones de los jugadores
        Posicion[] posJugadoresSag = sp.misJugadores();
        Posicion[] posJugadoresRivales = sp.rivales();

        // Crear jugadores en la primera iteracion
        if (sp.iteracion() == 0) {
            // Jugadores sag
            JugadorDetalle[] jdetalle = sp.detalleMisJugadores();
            jugadores = new Jugador[jdetalle.length];
            for (int i = 0; i < jdetalle.length; i++) {
                Posicion posRef = alineacion3[i];
                if (jdetalle[i].esPortero()) {
                    jugadores[i] = new Portero(i, jdetalle[i], posRef);
                } // Determinar tipo segun la posicion de referencia
                else {
                    double y = posRef.getY();
                    if (y < -20) {
                        jugadores[i] = new Defensa(i, jdetalle[i], posRef);
                    } else if (y > 20) {
                        jugadores[i] = new Delantero(i, jdetalle[i], posRef);
                    } else {
                        jugadores[i] = new Central(i, jdetalle[i], posRef);
                    }
                }
                jugadores[i].setPosicionActual(posJugadoresSag[i]);
            } // Fin for

            // Jugadores rivales
            jdetalle = sp.detalleJugadoresRivales();
            rivales = new Jugador[jdetalle.length];
            for (int i = 0; i < jdetalle.length; i++) {
                if (jdetalle[i].esPortero()) {
                    rivales[i] = new JRival(i, jdetalle[i], true);
                } else {
                    rivales[i] = new JRival(i, jdetalle[i]);
                }
                rivales[i].setPosicionActual(posJugadoresRivales[i]);
            } // Fin for

        } // Fin if: crear jugadores en la primera iteracion



        // Actualizar datos jugadores y rivales
        for (int i = 0; i < posJugadoresRivales.length; i++) {
            rivales[i].update(sp, rivales, jugadores);
        }
        for (int i = 0; i < posJugadoresSag.length; i++) {
            jugadores[i].update(sp, jugadores, rivales);
        }



        // Establecer recuperadores/interceptores
        //----------------------------------------------------------------------

        // RECUPERADORES
        int[] rc = sp.getRecuperacionBalon();
        if (rc.length > 0) {
            int tBalon = rc[0];
            double[] puntoRecuperacion = sp.getTrayectoria(tBalon);

            Posicion posRc = new Posicion(puntoRecuperacion[0], puntoRecuperacion[1]);
            int[] recuperadoresSag = posRc.indicesMasCercanos(posJugadoresSag);

            // Mis 2 recuperadores mas proximos
            int rc1 = recuperadoresSag[0];
            int rc2 = recuperadoresSag[1];

            // El recuperador rival mas proximo
            Jugador rival = rivales[posRc.indiceMasCercano(posJugadoresRivales)];

            // Evaluar recuperadores
            jugadores[rc1].evaluarRecuperacion(posRc, rival, jugadores[rc2]);


            // INTERCEPCION
            // Busco posibilidades de interceptar a partir de la iteracion 1
            for (int i = 1; i < tBalon; i++) {
                double[] puntoIc = sp.getTrayectoria(i);
                // Si la altura del balon es correcta
                if (puntoIc[0] != puntoRecuperacion[0]
                        && puntoIc[1] != puntoRecuperacion[1]
                        && puntoIc[2] <= Constantes.ALTURA_CONTROL_BALON) {
                    posRc = new Posicion(puntoIc[0], puntoIc[1]);
                    recuperadoresSag = posRc.indicesMasCercanos(posJugadoresSag);

                    jugadores[recuperadoresSag[0]].evaluarIntercepcion(posRc, jugadores[recuperadoresSag[1]], i);
                }
            } // Fin for: posibilidades de interceptar
        } // Fin if: existen recuperadores


        // GOLPEADORES: REMATADORES/PASADORES
        int[] golpeadoresSag = sp.puedenRematar();
        int totalGolpeadoresSag = golpeadoresSag.length;
        if (totalGolpeadoresSag > 0) {
            int jRt = golpeadoresSag[0];
            // Si hay varios golpeadores me quedo con el que tenga mejor precision
            // o mejor disparo
            if (totalGolpeadoresSag > 1) {
                for (int rt : golpeadoresSag) {
                    double error = sp.getErrorJugador(rt);
                    if (error == sp.getErrorJugador(jRt)
                            && sp.getRemateJugador(rt) > sp.getRemateJugador(jRt)) {
                        jRt = rt;
                    } else if (error > sp.getErrorJugador(jRt)) {
                        jRt = rt;
                    }
                } // End for: recorrer golpeadores
            } // End if: mas de un golpeador

            // Marcar jugador como rematador
            Jugador j = jugadores[jRt];
            j.setRematador(true);

        } // Fin if: existen rematadores


        // Recorrer jugadores
        //----------------------------------------------------------------------
        for (Jugador j : jugadores) {
            // 1. Posicionar jugadores :::::::::::::::::::::::::::::::
            // Recuperadores
            if (j.isRecuperador()) {
                comandos.add(new ComandoIrA(j.getIndice(), j.getPosicionDestino()));
            }
            else if (j.isInterceptor()) {
                comandos.add(new ComandoIrA(j.getIndice(), j.getPosicionDestino()));
            }
            // Resto de jugadores
            else {
                // Cambiar posicion de referencia en funcion de los goles
                // Si el rival gana
                if (golesRival - golesSag > 2) {
                    j.setPosicionReferencia(alineacion2[j.getIndice()]);
                } // Yo gano
                else if (golesSag - golesRival > 2) {
                    j.setPosicionReferencia(alineacion3[j.getIndice()]);
                } else {
                    j.setPosicionReferencia(alineacion1[j.getIndice()]);
                }

                comandos.add(j.irAPosicionDestino());
            }



            // 2. Rematadores/Pasadores :::::::::::::::::::::::::::::::
            if (j.isRematador()) {
                comandos.add(j.GolpearBalon());
            }

        } // Fin for: recorrer jugadores

        //Retorna la lista de comandos
        return comandos;
    }
}
